home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Turbo Pascal V7 / TVDEMOS.ZIP / TVRDEMO.PAS < prev   
Pascal/Delphi Source File  |  1992-11-03  |  15KB  |  598 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Vision Demo                            }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. { Turbo Vision demo program. This program demonstrates the use of
  9.   resource files and overlays to build a Turbo Vision application.
  10.   This program duplicates the functionality of TVDEMO but gets the
  11.   definition of menus, status line, and various dialogs off of a
  12.   resource file. GENRDEMO.PAS generates the resource file that is used
  13.   by this program.  To build this program, execute the batch file,
  14.   MKRDEMO.BAT which will create the resource file and overlay file
  15.   and copy them into the TVRDEMO.EXE file where this program looks
  16.   for them.
  17.  
  18.   Note: This program is designed for real-mode use only.
  19. }
  20.  
  21. program TVRDemo;
  22.  
  23. {$X+,S-}
  24. {$M 16384,8192,655360}
  25.  
  26. uses
  27.   Dos, Objects, Drivers, Memory, Views, Menus, Dialogs, StdDlg, HistList,
  28.   MsgBox, App, DemoCmds, DemoStrs, Gadgets, Puzzle, Calendar, AsciiTab,
  29.   Calc, HelpFile, DemoHelp, ColorSel, MouseDlg, Editors, Overlay;
  30.  
  31. { If you get a FILE NOT FOUND error when compiling this program,
  32.   use the MKRDEMO.BAT file described above.
  33. }
  34.  
  35. {$O Views}
  36. {$O Menus}
  37. {$O Dialogs}
  38. {$O StdDlg}
  39. {$O MsgBox}
  40. {$O App}
  41. {$O HelpFile}
  42. {$O Gadgets}
  43. {$O Puzzle}
  44. {$O Calendar}
  45. {$O AsciiTab}
  46. {$O Calc}
  47. {$O ColorSel}
  48. {$O MouseDlg}
  49. {$O Editors}
  50.  
  51. const
  52.   HeapSize = 48 * (1024 div 16);  { Save 48k heap for main program }
  53.  
  54.   { Desktop file signature information }
  55.   SignatureLen = 21;
  56.   DSKSignature : string[SignatureLen] = 'TV Demo Desktop File'#26;
  57.  
  58. var
  59.   ClipWindow: PEditWindow;
  60.  
  61. type
  62.  
  63.   { TTVDemo }
  64.  
  65.   PTVDemo = ^TTVDemo;
  66.   TTVDemo = object(TApplication)
  67.     Clock: PClockView;
  68.     Heap: PHeapView;
  69.     constructor Init;
  70.     procedure FileOpen(WildCard: PathStr);
  71.     function OpenEditor(FileName: FNameStr; Visible: Boolean): PEditWindow;
  72.     procedure GetEvent(var Event: TEvent); virtual;
  73.     function GetPalette: PPalette; virtual;
  74.     procedure HandleEvent(var Event: TEvent); virtual;
  75.     procedure Idle; virtual;
  76.     procedure InitMenuBar; virtual;
  77.     procedure InitStatusLine; virtual;
  78.     procedure LoadDesktop(var S: TStream);
  79.     procedure OutOfMemory; virtual;
  80.     procedure StoreDesktop(var S: TStream);
  81.   end;
  82.  
  83. type
  84.   PProtectedStream = ^TProtectedStream;
  85.   TProtectedStream = object(TBufStream)
  86.     procedure Error(Code, Info: Integer); virtual;
  87.   end;
  88.  
  89. var
  90.   EXEName: PathStr;
  91.   RezFile: TResourceFile;
  92.   RezStream: PStream;
  93.   Strings: PStringList;
  94.  
  95. { CalcHelpName }
  96.  
  97. function CalcHelpName: PathStr;
  98. var
  99.   EXEName: PathStr;
  100.   Dir: DirStr;
  101.   Name: NameStr;
  102.   Ext: ExtStr;
  103. begin
  104.   if Lo(DosVersion) >= 3 then EXEName := ParamStr(0)
  105.   else EXEName := FSearch('TVDEMO.EXE', GetEnv('PATH'));
  106.   FSplit(EXEName, Dir, Name, Ext);
  107.   if Dir[Length(Dir)] = '\' then Dec(Dir[0]);
  108.   CalcHelpName := FSearch('DEMOHELP.HLP', Dir);
  109. end;
  110.  
  111. { Resource MessageBox wrappers }
  112.  
  113. function RMessageBox(StrNum: Word; Param: Pointer; Flags: Word): Word;
  114. begin
  115.   RMessageBox := MessageBox(Strings^.Get(StrNum), Param, Flags);
  116. end;
  117.  
  118. function RMessageBoxRect(var Rect: TRect; StrNum: Word; Param: Pointer;
  119.   Flags: Word): Word;
  120. begin
  121.   RMessageBoxRect := MessageBoxRect(Rect, Strings^.Get(StrNum), Param,
  122.     Flags);
  123. end;
  124.  
  125. { Editor dialog call-back }
  126.  
  127. function DoEditDialog(Dialog: Integer; Info: Pointer): Word; far;
  128. var
  129.   R: TRect;
  130.   T: TPoint;
  131.  
  132.   function ExecDialog(const Dialog: String; Param: Pointer): Word;
  133.   begin
  134.     ExecDialog := Application^.ExecuteDialog(PDialog(RezFile.Get(Dialog)),
  135.       Param);
  136.   end;
  137.  
  138. begin
  139.   case Dialog of
  140.     edOutOfMemory:
  141.       DoEditDialog := RMessageBox(sNoMem, nil, mfError + mfOkButton);
  142.     edReadError:
  143.       DoEditDialog := RMessageBox(sErrorReading, @Info, mfError + mfOkButton);
  144.     edWriteError:
  145.       DoEditDialog := RMessageBox(sErrorWriting, @Info, mfError + mfOkButton);
  146.     edCreateError:
  147.       DoEditDialog := RMessageBox(sErrorCreating, @Info, mfError + mfOkButton);
  148.     edSaveModify:
  149.       DoEditDialog := RMessageBox(sModified, @Info,
  150.         mfInformation + mfYesNoCancel);
  151.     edSaveUntitled:
  152.       DoEditDialog := RMessageBox(sSaveUntitled, nil,
  153.         mfInformation + mfYesNoCancel);
  154.     edSaveAs:
  155.       DoEditDialog := ExecDialog('SaveAsDialog', Info);
  156.     edFind:
  157.       DoEditDialog := ExecDialog('FindDialog', Info);
  158.     edSearchFailed:
  159.       DoEditDialog := RMessageBox(sStrNotFound, nil, mfError + mfOkButton);
  160.     edReplace:
  161.       DoEditDialog := ExecDialog('ReplaceDialog', Info);
  162.     edReplacePrompt:
  163.       begin
  164.         { Avoid placing the dialog on the same line as the cursor }
  165.         R.Assign(0, 1, 40, 8);
  166.         R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  167.         Desktop^.MakeGlobal(R.B, T);
  168.         Inc(T.Y);
  169.         if TPoint(Info).Y <= T.Y then
  170.           R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  171.         DoEditDialog := RMessageBoxRect(R, sReplace, nil,
  172.           mfYesNoCancel + mfInformation);
  173.       end;
  174.   end;
  175. end;
  176.  
  177. { TProtectedStream }
  178.  
  179. procedure TProtectedStream.Error(Code, Info: Integer);
  180. begin
  181.   DoneHistory;
  182.   DoneSysError;
  183.   DoneEvents;
  184.   DoneVideo;
  185.   DoneMemory;
  186.  
  187.   Writeln('Error in stream: Code = ', Code, ' Info = ', Info);
  188.   Halt(1);
  189. end;
  190.  
  191. { TTVDemo }
  192. constructor TTVDemo.Init;
  193. var
  194.   R: TRect;
  195.   I: Integer;
  196.   FileName: PathStr;
  197. begin
  198.   { Initalize editor heap }
  199.   MaxHeapSize := HeapSize;
  200.  
  201.   { Initialize resource file }
  202.   RezStream := New(PProtectedStream, Init(EXEName, stOpenRead, 4096));
  203.   RezFile.Init(RezStream);
  204.  
  205.   RegisterObjects;
  206.   RegisterViews;
  207.   RegisterMenus;
  208.   RegisterDialogs;
  209.   RegisterApp;
  210.   RegisterStdDlg;
  211.   RegisterColorSel;
  212.  
  213.   RegisterHelpFile;
  214.   RegisterPuzzle;
  215.   RegisterCalendar;
  216.   RegisterAsciiTab;
  217.   RegisterCalc;
  218.   RegisterEditors;
  219.  
  220.   RegisterType(RStringList);
  221.  
  222.   Strings := PStringList(RezFile.Get('Strings'));
  223.  
  224.   inherited Init;
  225.  
  226.   { Initialize demo gadgets }
  227.  
  228.   GetExtent(R);
  229.   R.A.X := R.B.X - 9; R.B.Y := R.A.Y + 1;
  230.   Clock := New(PClockView, Init(R));
  231.   Insert(Clock);
  232.  
  233.   GetExtent(R);
  234.   Dec(R.B.X);
  235.   R.A.X := R.B.X - 9; R.A.Y := R.B.Y - 1;
  236.   Heap := New(PHeapView, Init(R));
  237.   Insert(Heap);
  238.  
  239.   DisableCommands([cmSave, cmSaveAs, cmCut, cmCopy, cmPaste, cmClear,
  240.     cmUndo, cmFind, cmReplace, cmSearchAgain, cmCloseAll]);
  241.   EditorDialog := DoEditDialog;
  242.   ClipWindow := OpenEditor('', False);
  243.   if ClipWindow <> nil then
  244.   begin
  245.     Clipboard := ClipWindow^.Editor;
  246.     Clipboard^.CanUndo := False;
  247.   end;
  248.  
  249.   for I := 1 to ParamCount do
  250.   begin
  251.     FileName := ParamStr(I);
  252.     if FileName[Length(FileName)] = '\' then
  253.       FileName := FileName + '*.*';
  254.     if (Pos('?', FileName) = 0) and (Pos('*', FileName) = 0) then
  255.       OpenEditor(FExpand(FileName), True)
  256.     else FileOpen(FileName);
  257.   end;
  258. end;
  259.  
  260. function TTVDemo.OpenEditor(FileName: FNameStr; Visible: Boolean): PEditWindow;
  261. var
  262.   P: PView;
  263.   R: TRect;
  264. begin
  265.   DeskTop^.GetExtent(R);
  266.   P := Application^.ValidView(New(PEditWindow,
  267.     Init(R, FileName, wnNoNumber)));
  268.   if not Visible then P^.Hide;
  269.   DeskTop^.Insert(P);
  270.   OpenEditor := PEditWindow(P);
  271. end;
  272.  
  273. procedure TTVDemo.FileOpen(WildCard: PathStr);
  274. var
  275.   FileName: PathStr;
  276. begin
  277.   FileName := '*.*';
  278.   if ExecuteDialog(PDialog(RezFile.Get('FileOpenDialog')),
  279.       @FileName) <> cmCancel then
  280.     OpenEditor(FileName, True);
  281. end;
  282.  
  283. procedure TTVDemo.GetEvent(var Event: TEvent);
  284. var
  285.   W: PWindow;
  286.   HFile: PHelpFile;
  287.   HelpStrm: PDosStream;
  288. const
  289.   HelpInUse: Boolean = False;
  290. begin
  291.   TApplication.GetEvent(Event);
  292.   case Event.What of
  293.     evCommand:
  294.       if (Event.Command = cmHelp) and not HelpInUse then
  295.       begin
  296.         HelpInUse := True;
  297.         HelpStrm := New(PDosStream, Init(CalcHelpName, stOpenRead));
  298.         HFile := New(PHelpFile, Init(HelpStrm));
  299.         if HelpStrm^.Status <> stOk then
  300.         begin
  301.           RMessageBox(sErrorHelp, nil, mfError + mfOkButton);
  302.           Dispose(HFile, Done);
  303.         end
  304.         else
  305.         begin
  306.           W := New(PHelpWindow,Init(HFile, GetHelpCtx));
  307.           if ValidView(W) <> nil then
  308.           begin
  309.             ExecView(W);
  310.             Dispose(W, Done);
  311.           end;
  312.           ClearEvent(Event);
  313.         end;
  314.         HelpInUse := False;
  315.       end;
  316.     evMouseDown:
  317.       if Event.Buttons <> 1 then Event.What := evNothing;
  318.   end;
  319. end;
  320.  
  321. function TTVDemo.GetPalette: PPalette;
  322. const
  323.   CNewColor = CAppColor + CHelpColor;
  324.   CNewBlackWhite = CAppBlackWhite + CHelpBlackWhite;
  325.   CNewMonochrome = CAppMonochrome + CHelpMonochrome;
  326.   P: array[apColor..apMonochrome] of string[Length(CNewColor)] =
  327.     (CNewColor, CNewBlackWhite, CNewMonochrome);
  328. begin
  329.   GetPalette := @P[AppPalette];
  330. end;
  331.  
  332. procedure TTVDemo.HandleEvent(var Event: TEvent);
  333.  
  334. procedure ChangeDir;
  335. begin
  336.   ExecuteDialog(PDialog(RezFile.Get('ChDirDialog')), nil);
  337. end;
  338.  
  339. procedure Puzzle;
  340. var
  341.   P: PPuzzleWindow;
  342. begin
  343.   P := New(PPuzzleWindow, Init);
  344.   P^.HelpCtx := hcPuzzle;
  345.   InsertWindow(P);
  346. end;
  347.  
  348. procedure Calendar;
  349. var
  350.   P: PCalendarWindow;
  351. begin
  352.   P := New(PCalendarWindow, Init);
  353.   P^.HelpCtx := hcCalendar;
  354.   InsertWindow(P);
  355. end;
  356.  
  357. procedure About;
  358. var
  359.   D: PDialog;
  360.   Control: PView;
  361.   R: TRect;
  362. begin
  363.   ExecuteDialog(PDialog(RezFile.Get('AboutDialog')), nil);
  364. end;
  365.  
  366. procedure AsciiTab;
  367. var
  368.   P: PAsciiChart;
  369. begin
  370.   P := New(PAsciiChart, Init);
  371.   P^.HelpCtx := hcAsciiTable;
  372.   InsertWindow(P);
  373. end;
  374.  
  375. procedure Calculator;
  376. var
  377.   P: PCalculator;
  378. begin
  379.   P := New(PCalculator, Init);
  380.   P^.HelpCtx := hcCalculator;
  381.   InsertWindow(P);
  382. end;
  383.  
  384. procedure Colors;
  385. begin
  386.   if ExecuteDialog(PDialog(RezFile.Get('ColorSelectDialog')),
  387.     Application^.GetPalette) <> cmCancel then
  388.   begin
  389.     DoneMemory;
  390.     ReDraw;
  391.   end;
  392. end;
  393.  
  394. procedure Mouse;
  395. var
  396.   D: PDialog;
  397. begin
  398.   D := New(PMouseDialog, Init);
  399.   D^.HelpCtx := hcOMMouseDBox;
  400.   ExecuteDialog(D, @MouseReverse);
  401. end;
  402.  
  403. procedure RetrieveDesktop;
  404. var
  405.   S: PStream;
  406.   Signature: string[SignatureLen];
  407. begin
  408.   S := New(PBufStream, Init('TVRDEMO.DSK', stOpenRead, 1024));
  409.   if LowMemory then OutOfMemory
  410.   else if S^.Status <> stOk then
  411.     RMessageBox(sErrorOpenDesk, nil, mfOkButton + mfError)
  412.   else
  413.   begin
  414.     Signature[0] := Char(SignatureLen);
  415.     S^.Read(Signature[1], SignatureLen);
  416.     if Signature = DSKSignature then
  417.     begin
  418.       LoadDesktop(S^);
  419.       LoadIndexes(S^);
  420.       LoadHistory(S^);
  421.       if S^.Status <> stOk then
  422.         RMessageBox(sErrorReadingDesk, nil, mfOkButton + mfError);
  423.     end
  424.     else
  425.       RMessageBox(sDeskInvalid, nil, mfOkButton + mfError);
  426.   end;
  427.   Dispose(S, Done);
  428. end;
  429.  
  430. procedure SaveDesktop;
  431. var
  432.   S: PStream;
  433.   F: File;
  434. begin
  435.   S := New(PBufStream, Init('TVRDEMO.DSK', stCreate, 1024));
  436.   if not LowMemory and (S^.Status = stOk) then
  437.   begin
  438.     S^.Write(DSKSignature[1], SignatureLen);
  439.     StoreDesktop(S^);
  440.     StoreIndexes(S^);
  441.     StoreHistory(S^);
  442.     if S^.Status <> stOk then
  443.     begin
  444.       RMessageBox(sErrorDeskCreate, nil, mfOkButton + mfError);
  445.       {$I-}
  446.       Dispose(S, Done);
  447.       Assign(F, 'TVRDEMO.DSK');
  448.       Erase(F);
  449.       Exit;
  450.     end;
  451.   end;
  452.   Dispose(S, Done);
  453. end;
  454.  
  455. procedure FileNew;
  456. begin
  457.   OpenEditor('', True);
  458. end;
  459.  
  460. procedure ShowClip;
  461. begin
  462.   ClipWindow^.Select;
  463.   ClipWindow^.Show;
  464. end;
  465.  
  466. begin
  467.   inherited HandleEvent(Event);
  468.   case Event.What of
  469.     evCommand:
  470.       begin
  471.         case Event.Command of
  472.           cmOpen: FileOpen('*.*');
  473.           cmNew: FileNew;
  474.           cmShowClip: ShowClip;
  475.           cmChangeDir: ChangeDir;
  476.           cmAbout: About;
  477.           cmPuzzle: Puzzle;
  478.           cmCalendar: Calendar;
  479.           cmAsciiTab: AsciiTab;
  480.           cmCalculator: Calculator;
  481.           cmColors: Colors;
  482.           cmMouse: Mouse;
  483.           cmSaveDesktop: SaveDesktop;
  484.           cmRetrieveDesktop: RetrieveDesktop;
  485.         else
  486.           Exit;
  487.         end;
  488.         ClearEvent(Event);
  489.       end;
  490.   end;
  491. end;
  492.  
  493. procedure TTVDemo.Idle;
  494.  
  495. function IsTileable(P: PView): Boolean; far;
  496. begin
  497.   IsTileable := (P^.Options and ofTileable <> 0) and
  498.     (P^.State and sfVisible <> 0);
  499. end;
  500.  
  501. begin
  502.   TApplication.Idle;
  503.   Clock^.Update;
  504.   Heap^.Update;
  505.   if Desktop^.FirstThat(@IsTileable) <> nil then
  506.     EnableCommands([cmTile, cmCascade])
  507.   else
  508.     DisableCommands([cmTile, cmCascade]);
  509. end;
  510.  
  511. procedure TTVDemo.InitMenuBar;
  512. begin
  513.   MenuBar := PMenuBar(RezFile.Get('MenuBar'));
  514. end;
  515.  
  516. procedure TTVDemo.InitStatusLine;
  517. begin
  518.   StatusLine := PStatusLine(RezFile.Get('StatusLine'));
  519. end;
  520.  
  521. procedure TTVDemo.OutOfMemory;
  522. begin
  523.   RMessageBox(sNoMem, nil, mfError + mfOkButton);
  524. end;
  525.  
  526. { Since the safety pool is only large enough to guarantee that allocating
  527.   a window will not run out of memory, loading the entire desktop without
  528.   checking LowMemory could cause a heap error.  This means that each
  529.   window should be read individually, instead of using Desktop's Load.
  530. }
  531.  
  532. procedure TTVDemo.LoadDesktop(var S: TStream);
  533. var
  534.   P: PView;
  535.   Pal: PString;
  536.  
  537. procedure CloseView(P: PView); far;
  538. begin
  539.   Message(P, evCommand, cmClose, nil);
  540. end;
  541.  
  542. begin
  543.   if Desktop^.Valid(cmClose) then
  544.   begin
  545.     Desktop^.ForEach(@CloseView); { Clear the desktop }
  546.     repeat
  547.       P := PView(S.Get);
  548.       Desktop^.InsertBefore(ValidView(P), Desktop^.Last);
  549.     until P = nil;
  550.     Pal := S.ReadStr;
  551.     if Pal <> nil then
  552.     begin
  553.       Application^.GetPalette^ := Pal^;
  554.       DoneMemory;
  555.       Application^.ReDraw;
  556.       DisposeStr(Pal);
  557.     end;
  558.   end;
  559. end;
  560.  
  561. procedure TTVDemo.StoreDesktop(var S: TStream);
  562. var
  563.   Pal: PString;
  564.  
  565. procedure WriteView(P: PView); far;
  566. begin
  567.   if P <> Desktop^.Last then S.Put(P);
  568. end;
  569.  
  570. begin
  571.   Desktop^.ForEach(@WriteView);
  572.   S.Put(nil);
  573.   Pal := @Application^.GetPalette^;
  574.   S.WriteStr(Pal);
  575. end;
  576.  
  577. var
  578.   Demo: TTVDemo;
  579. begin
  580.   if Lo(DosVersion) >= 3 then EXEName := ParamStr(0)
  581.   else
  582.   begin
  583.     EXEName := FSearch('TVRDEMO.EXE', GetEnv('PATH'));
  584.     if EXEName = '' then PrintStr('TVRDEMO.EXE could not be found.'#13#10);
  585.   end;
  586.   OvrInit(EXEName);
  587.   OvrSetBuf(58 * 1024);
  588.   if OvrResult <> ovrOk then
  589.   begin
  590.     PrintStr('No overlays found in .EXE file.  Must use MKRDEMO.BAT to build.'#13#10);
  591.     Halt(1);
  592.   end;
  593.   Demo.Init;
  594.   Demo.Run;
  595.   Demo.Done;
  596. end.
  597.  
  598.